<?php

namespace app\admin\controller;

use app\admin\service\admin\FileService;
use app\admin\service\dev\FieldService;
use app\common\Constants;
use app\common\service\VerificationCodeService;
use think\App;
use think\exception\ValidateException;
use think\facade\Cache;
use think\facade\Db;
use think\response\Json;

class Base extends Admin
{
    public function __construct(
        App $app,
        protected VerificationCodeService $verificationCodeService,
    )
    {
        parent::__construct($app);
    }

    /**
     * 上传文件
     * @return \think\response\Json
     * @IgnorePermission
     */
    public function upload(): \think\response\Json
    {
        $file = $this->request->file('file');
        $edit = $this->request->post('edit');
        // 检查上传的文件是否符合要求
        FileService::validateFileType($file);
        // 查询是否已经存在相同的文件，如果有就不再上传了
        $fileInfo = FileService::getSameFileUrl($file);
        // 如果返回了相同的文件地址，则直接返回，否则执行查询
        if ($fileInfo) {
            return $this->success(['data' => $fileInfo]);
        } else {
            return $this->success(['data' => FileService::doUpload($file, $edit)]);
        }
    }

    /**
     * 获取动态选项数据
     * @return Json
     */
    public function getOptions(): Json
    {
        try {
            $params = $this->request->param([
                'menu_id/d',        // 菜单ID
                'field_name/s',     // 字段名
                'query/s',          // 远程搜索关键字
                'page/d',           // 当前页码
                // 'page_size/d',      // 每页数量
                'cascade_params/s', // 级联参数（JSON字符串）
            ]);

            // 参数校验
            if (empty($params['menu_id']) || empty($params['field_name'])) {
                return $this->error(['message' => '缺少必要的参数: menu_id 或 field_name']);
            }

            // 解析级联参数
            $cascadeParams = [];
            if (!empty($params['cascade_params'])) {
                $decoded = json_decode($params['cascade_params'], true);
                if (json_last_error() === JSON_ERROR_NONE && is_array($decoded)) {
                    $cascadeParams = $decoded;
                } else {
                    // 级联参数解析失败，可能需要返回错误或忽略，这里选择忽略并记录日志
                    trace('Cascade params decoding failed: ' . $params['cascade_params']);
                }
            }

            // 调用FieldService中的新方法获取数据
            $result = FieldService::getDynamicOptions(
                $params['menu_id'],
                $params['field_name'],
                $params['query'] ?? '',
                $params['page'] ?? 1,
                // $params['page_size'] ?? 20,
                $cascadeParams
            );

            return $this->success(['data' => $result]);

        } catch (\think\Exception\ValidateException $ve) {
            return $this->error(['message' => $ve->getMessage()]);
        } catch (\Exception $e) {
            // 生产环境应记录日志，避免直接抛出详细错误信息
            return $this->error(['message' => '系统错误: ' . $e->getMessage()]);
        }
    }

    /**
     * 发送短信验证码
     * @return \think\response\Json
     */
    public function sendSmsCode(): \think\response\Json
    {
        $mobile = $this->request->post('mobile');

        if (empty($mobile)) {
            throw new ValidateException(Constants::E_COMMON_DATA_VALIDATION_FAILED);
        }

        $code = $this->verificationCodeService->generateCode();
        $key = Constants::CACHE_VERIFICATION_CODE_KEY . $mobile;
        $this->verificationCodeService->cacheCode($key, $code);

        if (app()->isDebug()) {
            $data = ['mobile' => $mobile, 'code' => $code];
            trace($data, 'debug');
            return $this->success(['data' => $data]);
        } else {
            $this->verificationCodeService->send('sms', $mobile, $code);
            return $this->success();
        }
    }

    /**
     * 发送验证码
     *
     * @return \think\response\Json
     */
    public function sendEmailCode(): \think\response\Json
    {
        $email = $this->request->post('email');
        $username = $this->request->post('username', '用户');

        if (empty($email)) {
            throw new ValidateException(Constants::E_COMMON_DATA_VALIDATION_FAILED);
        }

        $code = $this->verificationCodeService->generateCode();
        $key = Constants::CACHE_VERIFICATION_CODE_KEY . $email;
        $this->verificationCodeService->cacheCode($key, $code);

        if (app()->isDebug()) {
            $data = ['mail' => $email, 'code' => $code];
            trace($data, 'debug');
            return $this->success(['data' => $data]);
        } else {
            $result = $this->verificationCodeService->send('email', $email, $code, ['username' => $username]);
            if ($result) {
                return $this->success();
            } else {
                return $this->error();
            }
        }
    }

    /**
     * 清理缓存
     *
     * @return \think\response\Json
     * @throws \think\db\exception\DbException
     */
    public function cleanCache(): \think\response\Json
    {
        $post = $this->request->post();
        $cache_key = $post['cache_key'];
        if (in_array('cache', $cache_key)) {
            Cache::clear();
        }
        if (in_array('log', $cache_key)) {
            Db::name('admin_log')->delete(true);
        }
        if (in_array('runtime', $cache_key)) {
            $runtimePath = app()->getRuntimePath();
            $result = delete_dir_recursively($runtimePath, false);
            if (!$result) {
                throw new \Exception(Constants::E_COMMON_CLEAN_RUNTIME_DATA_FAILED);
            }
        }
        return $this->success(['message' => lang('responses.success')]);
    }
}